var compression = require('compression');
var express = require("express");
var path = require("path");
var app = express();
var ejs = require('ejs');
var fs = require("fs");
var cacheMapWatcher = require("./cacheMapWatcher");//更新cacheMap
var NodeCache = require("node-cache");
var reactTools = require('react-tools');
var UglifyJS = require("uglify-js");
global.cache = new NodeCache();
global.easyMe = {};
easyMe.components = {};
var classPool = {};
var child_process = require('child_process');
global.Interface = {};
global.Api = require("../routes/common/api");
global.React = require('react');
global.xss = require('xss');
//var addons = require('react-addons');
//React.addons = addons;
global.ReactDOMServer = require("react-dom/server");
global.isUseGlobalCache = JSON.parse(fs.readFileSync("config.json")).isUseGlobalCache;
require('node-jsx').install();
easyMe.import = function(path) {
    return easyMe.components[path];
}
function execCmd(cmd, callback) {
    child_process.exec(cmd, function (error, stdout, stderr) {
        if(callback) {
            callback();
        }
    });
}
if(!fs.existsSync("routes/cache")) {
    execCmd("mkdir routes/cache");
} else {
    execCmd("rm -rf routes/cache", function() {
        execCmd("mkdir routes/cache");
    });
}
if(!isUseGlobalCache) {
    cacheMapWatcher.clearCacheMap();
}
global.replaceAll = function(str, s1,s2) {
    return str.replace(new RegExp(s1,"gm"),s2);
}
function insertDataStreamStore(jsText) {
    var reactClassPos = jsText.indexOf("React.createClass({");
    if(reactClassPos > -1) {
        var insertStartPos = reactClassPos + "React.createClass({".length;
        var headJsText = jsText.substring(0, insertStartPos);
        var footJsText = jsText.substring(insertStartPos, jsText.length);
        jsText = headJsText + "valueLinked: function(attr, id) {if(typeof $ == 'undefined'){return};var self = this;var timer = null;if(!$('#' + id).isBind) {$('#' + id).isBind = true;var val = '';setInterval(function() {if($('#' + id).length > 0) {if(!timer) {timer = setInterval(function () {clearInterval(timer);$('#' + id).on('keyup change', function () {val = $('#' + id).val();self.state.data[attr] = $('#' + id).val();}); }, 0);}}}, 0);}},\n\tapply: function() {\n\t\tthis.setState(this.state);\n\t}," + footJsText;
    }
    return jsText;
}
global.use = function(pathArray, callback) {
    var classArray = [];
    for(var index = 0; index < pathArray.length; index++) {
        var path = pathArray[index];
        if(classPool[path]) {
            classArray.push(classPool[path]);
            continue;
        }
        var tplText = "";
        if(path.indexOf("Service.js") != -1) {
            var tplName = path.split("/")[2];
            var fileName = path.split("/")[3].substring(0, path.split("/")[3].indexOf(".js"));
            var jsText = fs.readFileSync(path).toString();
            var jsUrl = path.substring(0, path.lastIndexOf("/")) + "/" + fileName + "Cache.js";
            fs.writeFileSync(jsUrl, jsText);
        } else if(path.indexOf("widget") != -1) {
            
            var tplName = path.split("/")[3];
            var fileName = path.split("/")[4].substring(0, path.split("/")[4].indexOf(".js"));
            var tplUrl = "public/javascripts/widget/" + tplName + "/" + fileName + ".html";
            var jsText = fs.readFileSync(path).toString();
            try {
                tplText = fs.readFileSync(tplUrl).toString();
            } catch(e) {
                tplText = "";
            }
            jsText = replaceAll(jsText, "~" + fileName, tplText.toString());
            var jsUrl = path.substring(0, path.lastIndexOf("/")) + "/" + fileName + "Cache.js";
            fs.writeFileSync(jsUrl, jsText);
        } else if(path.indexOf("public/common") > -1 || path.indexOf("public/component") > -1) {
            var fileName = path.split("/")[2].substring(0, path.split("/")[2].indexOf(".js"));
            var jsText = fs.readFileSync(path).toString();
            var jsUrl = path.substring(0, path.lastIndexOf("/")) + "/" + fileName + "Cache.js";
            fs.writeFileSync(jsUrl, jsText);
        }  else {
            var tplName = path.split("/")[2];
            var fileName = path.split("/")[3].substring(0, path.split("/")[3].indexOf(".js"));
            var jsText = fs.readFileSync(path).toString();
            try {
                tplText = fs.readFileSync("views/tpl/" + tplName + "/" + fileName + ".html").toString();
            } catch(e) {
                tplText = "";
            }
            jsText = replaceAll(jsText, "~" + fileName, tplText.toString());
            var jsUrl = path.substring(0, path.lastIndexOf("/")) + "/" + fileName + "Cache.js";
            jsText = insertDataStreamStore(jsText);
            fs.writeFileSync(jsUrl, jsText);
        }
        jsText = reactTools.transform(jsText, null);//后台编译js文件
        jsText = UglifyJS.minify(jsText).code;//压缩js文件
        if(isUseGlobalCache) {
            cacheMapWatcher.updateCacheMap(path, jsText);
        }
        var classTpl = require("../" + jsUrl);
        easyMe.components[path] = classTpl;
        classPool[path] = classTpl;
        classArray.push(classTpl);
        //execCmd("rm -rf " + jsUrl);
        fs.unlinkSync(jsUrl);
    }
    callback.apply(null, classArray);
}
var config = function() {
    app.engine('.html', ejs.__express);
    app.set('view engine', 'html');
    app.use(express.bodyParser());
}
function getClientIp(req) {
    var clientIp = req.headers['x-forwarded-for'] ||
        req.connection.remoteAddress ||
        req.socket.remoteAddress ||
        req.connection.socket.remoteAddress;
    if(clientIp.indexOf("f:") > -1) {
        return clientIp.split("f:")[1];
    } else {
        return clientIp;
    }
}
var configStyle = function() {
    var dirname = __dirname;
    dirname = dirname.substring(0, dirname.lastIndexOf("\\"));
    app.use(compression()); //use compression
    app.use(express.static(path.join(dirname, 'public')));
}
app.watch = function(port) {
    var watchString = fs.readFileSync("./routes/watch.json").toString();
    var watchJson = JSON.parse(watchString);
    var requestList = watchJson.request;
    global.routeList = requestList;
    for(var index = 0; index < requestList.length; index++) {
        var page = require(requestList[index].url);
        var requestName = requestList[index].requestName;
        var routeAction = page[requestName];
        (function(routeAction, requestName, requestList, index, page) {
            page[requestName] = function(req, res) {//拦截请求
                var cookie = require("cookie");
                if(req.headers) {
                    req.headers["X-Real-IP-Cus-Node"] = getClientIp(req);
                }
                if(req.headers && req.headers.cookie) {
                    req.headers["x-token"] = cookie.parse(req.headers.cookie).token;
                }
                if(requestList[index].isLogin) {
                    var self = this;
                    require("../routes/common/login").checkLogin(req, res, function() {
                        routeAction.call(self, req, res);
                    });
                } else {
                    routeAction.call(this, req, res);
                }
            }
            app[requestList[index].type](requestList[index].route, page[requestName]);
        })(routeAction, requestName, requestList, index, page);
    }
    configStyle();
    app.listen(port);
}
var conf = {
    init: function() {
        config();
        return {
            path:path,
            ejs: ejs,
            app:app
        }
    }
}
exports.conf = conf;